package com.sinog.biz.service.business.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sinog.biz.mapper.havexml.DepartmentMapper;
import com.sinog.biz.mapper.havexml.PrisonerFxMapper;
import com.sinog.biz.mapper.havexml.PrisonerMainMapper;
import com.sinog.biz.mapper.havexml.PrisonerSrMapper;
import com.sinog.biz.mapper.havexml.PrisonerXjxxMapper;
import com.sinog.biz.mapper.havexml.PrisonerZnMapper;
import com.sinog.biz.mapper.havexml.VerificationMapper;
import com.sinog.biz.mapper.havexml.other.PrisonerTransferMapper;
import com.sinog.biz.service.api.async.AsyncTask;
import com.sinog.biz.service.business.PrisonerTransferService;
import com.sinog.biz.util.CodeUrlUtils;
import com.sinog.biz.util.ConditionUtils;
import com.sinog.biz.util.IdGen;
import com.sinog.biz.util.smlib.Sm4;
import com.sinog.core.domain.PrisonerMain;
import com.sinog.core.domain.PrisonerTransfer;
import com.sinog.core.domain.PrisonerTs;
import com.sinog.core.model.UserDTO;
import com.sinog.core.util.JsonUtil;
import com.sinog.core.util.PageReturnUtil;
import com.sinog.core.util.StrUtil;
import com.sinog.core.utilbean.Constants;
import com.sinog.core.utilbean.Result;
import com.sinog.core.utilbean.ReturnCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;

/**
 * @desc 预安置管理 - 预安置人员迁移
 * @author wangxj
 * @date 2022/3/23 14:06
 */
@Slf4j
@Service
public class PrisonerTransferServiceImpl implements PrisonerTransferService {

    @Autowired
    private PrisonerTransferMapper prisonerTransferMapper;
    @Autowired
    private PrisonerMainMapper prisonerMainMapper;
    @Autowired
    private DepartmentMapper departmentMapper;
    @Autowired
    private AsyncTask asyncTask;
    @Autowired
    private PrisonerFxMapper prisonerFxMapper;
    @Autowired
    private PrisonerZnMapper prisonerZnMapper;
    @Autowired
    private PrisonerSrMapper prisonerSrMapper;
    @Autowired
    private PrisonerXjxxMapper prisonerXjxxMapper;
    @Autowired
    private VerificationMapper verificationMapper;
    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 预安置管理 - 预安置人员迁移 - 发起迁移/接收迁移列表
     * @param map 查询参数
     * @param pageIndex 起始页
     * @param pageSize 止页
     * @return String
     */
    @Override
    public String getFqTranslateBaseInfoList(Map<String,Object> map,Integer pageIndex,Integer pageSize) {
        Page<Map<String,String>> page = new Page<>(pageIndex + 1,pageSize);
        //身份证加密
        if(ObjectUtils.isNotEmpty(map.get("shenKey"))) {
            map.put("shenKey",Sm4.encryptEcb(map.get("shenKey").toString()));
        }
        //处理其他条件参数
        List<String> qitaKey = null;
        String qitaKeyStr = (String)map.get("qitaKey");
        if(StringUtils.isNotBlank(qitaKeyStr)) {
            String[] split = qitaKeyStr.split(",");
            qitaKey = Arrays.asList(split);
        }
        map.put("qitaKey",qitaKey);
        //查询
        List<Map<String,String>> fqTranslateBaseInfoList = prisonerTransferMapper.getFqTranslateBaseInfoList(page,map);
        page.setRecords(fqTranslateBaseInfoList);
        map.put("total",String.valueOf(fqTranslateBaseInfoList.size()));
        CompletableFuture.runAsync(() -> {
            log.info("工作台-发起迁移/接收迁移列表-异步条件进入redis {}:"+Thread.currentThread().getName());
            ConditionUtils.searchConditions(map,map.get("account").toString(),redisTemplate);
        });
        return PageReturnUtil.pageReturn(page);
    }

    /**
     * 预安置管理 - 预安置人员迁移 - 添加页面 - 搜索条件(根据key模糊搜索)
     * @param key 服刑人员名称
     * @param departId 当前登录用户DepartId
     * @param level 当前登录用户level
     * @return List<Map < String,Object>>
     */
    @Override
    public List<Map<String,Object>> getPrisonerList(String key,String departId,String level) {
        return prisonerTransferMapper.getPrisonerList(key,departId,level);
    }

    /**
     * 描述
     * @param id id
     * @return Result
     */
    @Override
    public Result getTransferById(String id) {
        Map<String,String> map = prisonerTransferMapper.getTransferById(id);
        // 获取基本信息
        Map<String,String> baseInfoMap = prisonerTransferMapper.getBaseInfoByPriNum(id);
        if(!baseInfoMap.isEmpty()) {
            map.putAll(baseInfoMap);
        }
        if(!map.isEmpty()) {
            return Result.success(map);
        }
        return Result.failure(ReturnCode.SELECT_FAILED);
    }

    /**
     * 反显服刑人员基本信息
     * @param priNum 服刑编号
     * @return Map<String,Object>
     */
    @Override
    public Map<String,Object> getBaseInfoByPriNumMap(String priNum) {
        PrisonerMain prisonerMain = prisonerMainMapper.selectPrisonerMain(priNum);
        if(null != prisonerMain) {
            return JsonUtil.toMap(JsonUtil.toTextSetDate(prisonerMain, "yyyy-MM-dd"));
        }
        return new HashMap<>(16);
    }

    /**
     * 预安置管理 - 预安置人员迁移 - 添加页面 - 保存
     * @param dataStr 业务数据
     * @return Result
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result savePrisonerTransfer(String dataStr) {
        //实体参数
        PrisonerTransfer prisonerTransfer = JsonUtil.toBean(dataStr,PrisonerTransfer.class);
        PrisonerTs prisonerTs = new PrisonerTs();
        //参数转map
        Map<String,Object> jsonMap = JsonUtil.toMap(dataStr);
        //从参数中取出用户实体
        UserDTO user = JsonUtil.toBean((String)jsonMap.get("user"),UserDTO.class);
        //封装prisonerTransfer
        Date date = new Date();
        prisonerTransfer.setCreateTime(date);
        prisonerTransfer.setCreateUser(user.getAccount());
        prisonerTransfer.setUpdateTime(date);
        prisonerTransfer.setUpdateUser(user.getAccount());
        //封装prisonerTs
        prisonerTs.setCreateTime(date);
        prisonerTs.setCreateUser(user.getAccount());
        prisonerTs.setUpdateTime(date);
        prisonerTs.setUpdateUser(user.getAccount());
        String level = user.getLevel();
        //数据库中查询prisonerTransfer
        String priNum = prisonerTransfer.getPriNum();
        QueryWrapper<PrisonerTransfer> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(Constants.StrFinalValue.PRINUM,priNum).orderByDesc("create_time");
        PrisonerTransfer oldPrisonerTransfer = prisonerTransfer.selectOne(queryWrapper);
        if(StringUtils.isBlank(prisonerTransfer.getId())) {
            prisonerTransfer.setId(IdGen.strid());
        }
        // 标志位
        boolean flag = false;
        boolean flag1;
        // 审批状态: 0:撤回迁移状态 1:发起迁移状态 2:迁移成功状态 3:迁移拒绝状态 4:重新发起迁移状态
        boolean twoFlag = Constants.NumberStr.NUM_STR_TWO.equals(prisonerTransfer.getState());
        boolean threeFlag = Constants.NumberStr.NUM_STR_THREE.equals(prisonerTransfer.getState());
        boolean oneFlag = null != oldPrisonerTransfer && Constants.NumberStr.NUM_STR_ONE.equals(oldPrisonerTransfer.getState());
        boolean fourFlag = null != oldPrisonerTransfer && Constants.NumberStr.NUM_STR_FOUR.equals(oldPrisonerTransfer.getState());
        boolean defaultValue = Constants.NumberStr.NUM_STR_ONE.equals(prisonerTransfer.getState()) || Constants.NumberStr.NUM_STR_FOUR.equals(prisonerTransfer.getState());
        // 参数：迁移成功状态   数据库中：发起迁移状态、重新发起迁移状态
        if(twoFlag) {
            if(oneFlag || fourFlag) {
                Map<String,String> baseInfo = prisonerTransferMapper.getTransferById(oldPrisonerTransfer.getId());
                PrisonerMain prisonerMain = prisonerMainMapper.selectPrisonerMain(priNum);
                prisonerMain.setUpdateUser(user.getAccount());
                prisonerMain.setUpdateTime(date);
                if(Objects.equals(Constants.OrgLevel.LEVEL_QXSFJ,level)) {
                    prisonerMain.setNativepro(baseInfo.get("nativeInpro"));
                    prisonerMain.setNativecity(baseInfo.get("nativeIncity"));
                    prisonerMain.setNativecou(baseInfo.get("nativeIncou"));
                    prisonerMain.setNativevill(baseInfo.get("nativeInvill"));
                    prisonerMain.setNativeproName(baseInfo.get("nativeInproName"));
                    prisonerMain.setNativecityName(baseInfo.get("nativeIncityName"));
                    prisonerMain.setNativecouName(baseInfo.get("nativeIncouName"));
                    prisonerMain.setNativevillName(baseInfo.get("nativeInvillName"));
                    prisonerMain.setNativenum(baseInfo.get("nativeInnum"));
                    // 改变adduserid
                } else if(StrUtil.containsEquals(level,Constants.OrgLevel.LEVEL_JY,Constants.OrgLevel.LEVEL_KSS,Constants.OrgLevel.LEVEL_SJZX)) {
                    // 监狱户籍迁移成功后将main,fx,sr,zn,hc,xjxx,cjpg,zyjn,jxjs表更改addUserId
                    String departId = user.getDepartid();
                    prisonerMain.setAdduserid(departId);
                    prisonerMain.setPdanwei(departId);
                    prisonerMain.setPdanweiName(user.getDepartName());
                    prisonerMain.setPrisonFather(user.getOrgid());
                    prisonerFxMapper.updateAddUserIdByPriNum(departId,priNum);
                    prisonerSrMapper.updateAddUserIdByPriNum(departId,priNum);
                    prisonerZnMapper.updateAddUserIdByPriNum(departId,priNum);
                    prisonerSrMapper.updateAddUserIdByPriNum(departId,priNum);
                    verificationMapper.updateAddUserIdByPriNum(departId,priNum);
                    prisonerXjxxMapper.updateAddUserIdByPriNum(departId,priNum);
                    prisonerFxMapper.updateAddUserIdByPriNumNew(departId,priNum);
                }
                prisonerTransfer.setMoveInTime(date);
                //审批完成
                flag1 = prisonerMain.insertOrUpdate();
                flag = prisonerTransfer.insertOrUpdate();
                if(!flag && !flag1) {
                    return Result.failure(ReturnCode.SAVE_FAILED);
                }
                return Result.success(ReturnCode.SUCCESS);
            } else if(threeFlag) {
                if(oneFlag || fourFlag) {
                    // 接收方司法局拒绝
                    flag = prisonerTransfer.insertOrUpdate();
                } else if(fourFlag) {
                    // 司法局再次发起迁移
                    flag = prisonerTransfer.insertOrUpdate();
                } else if(twoFlag && fourFlag) {
                    // 司法所再次确认迁移
                    flag = prisonerTransfer.insertOrUpdate();
                } else if(defaultValue) {
                    // 默认发起迁移操作
                    prisonerTransfer.setDelFlag(Constants.NumberStr.NUM_STR_ZERO);
                    prisonerTransfer.setAdduserId(user.getDepartid());
                    // 设置跨省省份
                    prisonerTransfer.setTranProvince(prisonerTransfer.getNativepro());
                    // 社矫中心迁移单独处理
                    if(Objects.equals(prisonerTransfer.getPrisonUnit(),Constants.NumberStr.NUM_STR_ZERO_FIVE)) {
                        prisonerTransfer.setZpdanwei(prisonerTransfer.getNativevill()
                                                                     .concat(Constants.NumberStr.NUM_STR_X));
                        prisonerTransfer.setZpdanweiName(prisonerTransfer.getNativevillName()
                                                                         .concat(Constants.DepartmentName.DEPARTMENT_SJZX));
                    }
                    flag = prisonerTransfer.insertOrUpdate();
                    // 监狱发起后,同步跨省数据
                    if(StrUtil.containsEquals(level,Constants.OrgLevel.LEVEL_JY,Constants.OrgLevel.LEVEL_KSS,Constants.OrgLevel.LEVEL_SJZX)) {
                        // 获取本省省份标识
                        String localCode = CodeUrlUtils.getLocalCode();
                        // 获取跨省省份标识
                        String nativepro = prisonerTransfer.getNativepro();
                        if(!Objects.equals(localCode,nativepro)) {
                            asyncTask.send(priNum,prisonerTransfer.getNativepro());
                        }
                    }
                }
            } else if(twoFlag && fourFlag) {
                // 司法所再次确认迁移
                flag = prisonerTransfer.insertOrUpdate();
            } else if(defaultValue) {
                // 默认发起迁移操作
                prisonerTransfer.setDelFlag(Constants.NumberStr.NUM_STR_ZERO);
                prisonerTransfer.setAdduserId(user.getDepartid());
                // 设置跨省省份
                prisonerTransfer.setTranProvince(prisonerTransfer.getNativepro());
                // 社矫中心迁移单独处理
                if(Objects.equals(prisonerTransfer.getPrisonUnit(),Constants.NumberStr.NUM_STR_ZERO_FIVE)) {
                    prisonerTransfer.setZpdanwei(prisonerTransfer.getNativevill()
                                                                 .concat(Constants.NumberStr.NUM_STR_X));
                    prisonerTransfer.setZpdanweiName(prisonerTransfer.getNativevillName()
                                                                     .concat(Constants.DepartmentName.DEPARTMENT_SJZX));
                }
                flag = prisonerTransfer.insertOrUpdate();
                // 监狱发起后,同步跨省数据
                if(StrUtil.containsEquals(level,Constants.OrgLevel.LEVEL_JY,Constants.OrgLevel.LEVEL_KSS,Constants.OrgLevel.LEVEL_SJZX)) {
                    // 获取本省省份标识
                    String localCode = CodeUrlUtils.getLocalCode();
                    // 获取跨省省份标识
                    String nativepro = prisonerTransfer.getNativepro();
                    if(!Objects.equals(localCode,nativepro)) {
                        asyncTask.send(priNum,prisonerTransfer.getNativepro());
                    }
                }
            }
        } else if(threeFlag) {
            if(oneFlag || fourFlag) {
                // 接收方司法局拒绝
                flag = prisonerTransfer.insertOrUpdate();
            } else if(fourFlag) {
                // 司法局再次发起迁移
                flag = prisonerTransfer.insertOrUpdate();
            } else if(twoFlag && fourFlag) {
                // 司法所再次确认迁移
                flag = prisonerTransfer.insertOrUpdate();
            } else if(defaultValue) {
                // 默认发起迁移操作
                prisonerTransfer.setDelFlag(Constants.NumberStr.NUM_STR_ZERO);
                prisonerTransfer.setAdduserId(user.getDepartid());
                // 设置跨省省份
                prisonerTransfer.setTranProvince(prisonerTransfer.getNativepro());
                // 社矫中心迁移单独处理
                if(Objects.equals(prisonerTransfer.getPrisonUnit(),Constants.NumberStr.NUM_STR_ZERO_FIVE)) {
                    prisonerTransfer.setZpdanwei(prisonerTransfer.getNativevill()
                                                                 .concat(Constants.NumberStr.NUM_STR_X));
                    prisonerTransfer.setZpdanweiName(prisonerTransfer.getNativevillName()
                                                                     .concat(Constants.DepartmentName.DEPARTMENT_SJZX));
                }
                flag = prisonerTransfer.insertOrUpdate();
                // 监狱发起后,同步跨省数据
                if(StrUtil.containsEquals(level,Constants.OrgLevel.LEVEL_JY,Constants.OrgLevel.LEVEL_KSS,Constants.OrgLevel.LEVEL_SJZX)) {
                    // 获取本省省份标识
                    String localCode = CodeUrlUtils.getLocalCode();
                    // 获取跨省省份标识
                    String nativepro = prisonerTransfer.getNativepro();
                    if(!Objects.equals(localCode,nativepro)) {
                        asyncTask.send(priNum,prisonerTransfer.getNativepro());
                    }
                }
            }
        } else if(twoFlag && fourFlag) {
            // 司法所再次确认迁移
            flag = prisonerTransfer.insertOrUpdate();
        } else if(defaultValue) {
            // 默认发起迁移操作
            prisonerTransfer.setDelFlag(Constants.NumberStr.NUM_STR_ZERO);
            prisonerTransfer.setAdduserId(user.getDepartid());
            // 设置跨省省份
            prisonerTransfer.setTranProvince(prisonerTransfer.getNativepro());
            // 社矫中心迁移单独处理
            if(Objects.equals(prisonerTransfer.getPrisonUnit(),Constants.NumberStr.NUM_STR_ZERO_FIVE)) {
                prisonerTransfer.setZpdanwei(prisonerTransfer.getNativevill().concat(Constants.NumberStr.NUM_STR_X));
                prisonerTransfer.setZpdanweiName(prisonerTransfer.getNativevillName()
                                                                 .concat(Constants.DepartmentName.DEPARTMENT_SJZX));
            }
            flag = prisonerTransfer.insertOrUpdate();
            // 监狱发起后,同步跨省数据
            if(StrUtil.containsEquals(level,Constants.OrgLevel.LEVEL_JY,Constants.OrgLevel.LEVEL_KSS,Constants.OrgLevel.LEVEL_SJZX)) {
                // 获取本省省份标识
                String localCode = CodeUrlUtils.getLocalCode();
                // 获取跨省省份标识
                String nativepro = prisonerTransfer.getNativepro();
                if(!Objects.equals(localCode,nativepro)) {
                    asyncTask.send(priNum,prisonerTransfer.getNativepro());
                }
            }
        }
        // 过程记录
        if(StrUtil.containsEquals(level,Constants.OrgLevel.LEVEL_JY,Constants.OrgLevel.LEVEL_KSS,Constants.OrgLevel.LEVEL_SJZX)) {
            // 1:转监,2:更改户籍,3:核查
            prisonerTs.setType(Constants.NumberStr.NUM_STR_ONE);
        } else if(Objects.equals(Constants.OrgLevel.LEVEL_QXSFJ,level)) {
            prisonerTs.setType(Constants.NumberStr.NUM_STR_TWO);
        }
        prisonerTs.setAdduserId(user.getDepartid());
        createTsBean(prisonerTransfer,prisonerTs);
        boolean flag2 = prisonerTs.insertOrUpdate();
        if(!flag && !flag2) {
            return Result.failure(ReturnCode.SAVE_FAILED);
        }
        return Result.success(ReturnCode.SUCCESS);
    }

    /**
     * 记录流程
     * @param prisonerTransfer prisonerTransfer
     * @param prisonerTs prisonerTs
     */
    private void createTsBean(PrisonerTransfer prisonerTransfer,PrisonerTs prisonerTs) {
        prisonerTs.setId(IdGen.strid());
        prisonerTs.setPriNum(prisonerTransfer.getPriNum());
        prisonerTs.setNativepro(prisonerTransfer.getNativepro());
        prisonerTs.setNativecity(prisonerTransfer.getNativecity());
        prisonerTs.setNativecou(prisonerTransfer.getNativecou());
        prisonerTs.setNativevill(prisonerTransfer.getNativevill());
        prisonerTs.setNativeproName(prisonerTransfer.getNativeproName());
        prisonerTs.setNativecityName(prisonerTransfer.getNativecityName());
        prisonerTs.setNativecouName(prisonerTransfer.getNativecouName());
        prisonerTs.setNativevillName(prisonerTransfer.getNativevillName());
        prisonerTs.setNewNativepro(prisonerTransfer.getNativeInpro());
        prisonerTs.setNewNativecity(prisonerTransfer.getNativeIncity());
        prisonerTs.setNewNativecou(prisonerTransfer.getNativeIncou());
        prisonerTs.setNewNativevill(prisonerTransfer.getNativeInvill());
        prisonerTs.setNewNativeproName(prisonerTransfer.getNativeInproName());
        prisonerTs.setNewNativecityName(prisonerTransfer.getNativeIncityName());
        prisonerTs.setNewNativecouName(prisonerTransfer.getNativeIncouName());
        prisonerTs.setNewNativevillName(prisonerTransfer.getNativeInvillName());
        prisonerTs.setTranState(prisonerTransfer.getState());
        prisonerTs.setPdanwei(prisonerTransfer.getPdanwei());
        prisonerTs.setZpdanwei(prisonerTransfer.getZpdanwei());
        if(Objects.equals(prisonerTransfer.getPrisonUnit(),Constants.NumberStr.NUM_STR_ZERO_FIVE)) {
            prisonerTransfer.setZpdanwei(prisonerTransfer.getNativevill());
            prisonerTransfer.setZpdanweiName(prisonerTransfer.getNativevillName());
        }
        prisonerTs.setPriReason(prisonerTransfer.getQrdRemark());
        prisonerTs.setPhoneNumber(prisonerTransfer.getQrlxdh());
        prisonerTs.setFixedlineNumber(prisonerTransfer.getQrlxgh());
    }

    /**
     * 预安置管理 - 预安置人员迁移 - 发起迁移 - 撤回
     * @param id transfet编号
     * @return Result
     */
    @Override
    public Result toRevoke(String id) {
        PrisonerTransfer prisonerTransfer = prisonerTransferMapper.selectById(id);
        int num = 0;
        if(Constants.NumberStr.NUM_STR_ONE.equals(prisonerTransfer.getState()) || Constants.NumberStr.NUM_STR_FOUR.equals(prisonerTransfer.getState())) {
            num = prisonerTransferMapper.updatePrisonerTransferById(id,Constants.NumberStr.NUM_STR_ZERO);
        }
        if(0 < num) {
            return Result.success(ReturnCode.SUCCESS);
        }
        return Result.failure(ReturnCode.SAVE_FAILED);
    }

    /**
     * 预安置管理 - 预安置人员迁移 - 发起迁移 - 删除(逻辑删除)
     * @param id transfet编号
     * @return Result
     */
    @Override
    public Result toDelete(String id) {
        int num = 0;
        if(StringUtils.isNotBlank(id)) {
            num = prisonerTransferMapper.updatePrisonerTransferDelFlagById(id);
        }
        if(0 < num) {
            return Result.success(ReturnCode.SUCCESS);
        }
        return Result.failure(ReturnCode.DELETE_FAILED);
    }

    /**
     * 获取转监单位
     * @param code 当前省份标识
     * @param level 服刑单位(例、01:监狱,02:看守所,05:社矫中心)
     * @param departId 当前用户的departId
     * @return List<Map < String,Object>>
     */
    @Override
    public List<Map<String,Object>> getTransferUnit(String code,String level,String departId) {
        return departmentMapper.getTransferUnit(code,level,departId);
    }

    /**
     * 查找此人是否正在户籍迁移
     * @param priNums 服刑人员编号
     * @return Result
     */
    @Override
    public Result getTransferRecord(List<String> priNums) {
        int num = prisonerTransferMapper.getTransferRecord(priNums);
        if(0 < num) {
            return Result.failure(ReturnCode.AREASREDIS);
        }
        return Result.success(ReturnCode.SUCCESS);
    }

    /**
     * 根据核查编号获取推送基本信息
     * @param hcId 核查编号
     * @return Result
     */
    @Override
    public Result getBaseInfoByPriNum(String hcId) {
        return Result.success(prisonerTransferMapper.getBaseInfo(hcId));
    }
}